#include <iostream>
#include <cmath>
#include <vector>
#include <functional>
#include <fstream>
#include "bezier_curve.hpp"

const double PI = acos(-1);
/*
std::pair<double, double> heartshape(double t){
  double rt3 = sqrt(3);
  double x = -1 * rt3 * sin(t*2*PI);
  double y = 2./3*(rt3 * cos(2*PI*t) + sqrt(std::abs(rt3*sin(2*PI*t))));
  return std::make_pair(x, y);  
}

std::pair<double, double> d_heartshape(double t){  
  double rt3 = sqrt(3);  
  double dx_dt = (heartshape(t+1e-5).first - heartshape(t-1e-5).first)*1e4;
  double dy_dt = (heartshape(t+1e-5).second - heartshape(t-1e-5).second)*1e4;
  return std::make_pair(dx_dt, dy_dt);    
}  
*/

std::pair<double, double> heartshape(double t){
  double rt3 = sqrt(3);
  double x = -1 * rt3 * cos(t*2*PI);
  double y = 2./3*(rt3 * sin(2*PI*t) + sqrt(std::abs(rt3*cos(2*PI*t))));
  return std::make_pair(x, y);  
}

std::pair<double, double> d_heartshape(double t){  
  double rt3 = sqrt(3);  
  double dx_dt = (heartshape(t+1e-5).first - heartshape(t).first)*1e5;
  double dy_dt = (heartshape(t+1e-5).second - heartshape(t).second)*1e5;
  return std::make_pair(dx_dt, dy_dt);    
}  



void generateData(const std::string& filename, std::function<std::pair<double,double>(double)> f) {
    int N = 300;
    std::pair<double, double> coordinates; 
    std::ofstream datafile(filename);  
    if (datafile.is_open()) {  
        for (int i = 0; i <= N; i++) {
	  coordinates = f(i*1./N);
            datafile << coordinates.first<< " " << coordinates.second << std::endl;  
        }  
        datafile.close();  
    } else {  
        std::cerr << "Unable to open file";  
    }  
}  

void bezierData(const std::string& filename, std::vector<std::pair<double,double>>& p, std::vector<std::pair<double,double>> dy ) {
  int n = p.size(); 
    int N = 10;
    // 检查输入向量的大小是否一致  
    if(p.size() != dy.size()) {  
      // 如果 p 和 dy 的大小不一致，输出错误信息并返回  
      std::cerr << "Error: Size mismatch between p and dy" << std::endl;  
    return;  
    } 
    std::pair<double, double> coordinates;
    std::function<std::pair<double,double>(double)> f;
    std::ofstream datafile(filename);  
    if (datafile.is_open()) {
      for (int j = 0;j < n-1; j++){
	f = Bezier_curves(p[j],p[j+1],dy[j],dy[j+1]);
        for (int i = 0; i < N; i++) {
	  coordinates = f(i*1./N);
	  datafile << coordinates.first<< " " << coordinates.second << std::endl;  
        }
      }
        datafile.close();  
    } else {  
        std::cerr << "Unable to open file";  
    }  
} 

int main() {
  generateData("data.txt", heartshape);

  std::vector<std::function<std::pair<double,double>(double)>> BZ_curves(3);
  std::vector<std::pair<double,double>> p;
  std::vector<std::pair<double,double>> dy;
  int n = 0;
  //std::pair<double,double> temp;
  std::vector<std::string> filename = {"data10.txt", "data40.txt", "data160.txt"};
  for (int j : {10,40,160}){
     p.clear();
     dy.clear();
     for (int i = 0; i <= j; i++){
       p.push_back(heartshape((1.*i+0.1)/j));
       std::pair<double,double> temp = d_heartshape((1.*i+0.1)/j);
       temp = std::make_pair(temp.first/j,temp.second/j);
       //std::cout<<temp.first/j<<std::endl;
       dy.push_back(temp);
     }
     bezierData(filename[n],p,dy);
     n++;
  }
  return 0;
}
